package main

import (
    "errors"
    "fmt"
    "io"
    "net/http"
    "os"
    "io/ioutil"
    "strings"
    "log"
)    

func sayHello(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    fmt.Println(r.Form)
    fmt.Println("path", r.URL.Path)
    fmt.Println("scheme", r.URL.Scheme)
    fmt.Println(r.Form["url_long"])
    for k, v := range r.Form {
        fmt.Println("key:", k)
        fmt.Println("val:", strings.Join(v, ""))
    }

    // http.StatusInternalServerError
    w.WriteHeader(403)
    fmt.Fprintf(w, "Hello astaxie!!!!!!")

//    w.Write([]byte("500 - Something bad happened!"))
//    http.Error(w, "my own error message", http.StatusForbidden)
//    http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
}


func getRoot(w http.ResponseWriter, r *http.Request) {
    fmt.Printf("got / request\n")
    io.WriteString(w, "This is my website 1!\n")
}
func getHello(w http.ResponseWriter, r *http.Request) {
    fmt.Printf("got /hello request\n")
    io.WriteString(w, "Hello, HTTP!\n")
}

const keyServerAddr = "serverAddr"

func getRoot1(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    fmt.Printf("%s: got / request\n", ctx.Value(keyServerAddr))
    io.WriteString(w, "This is my website 2!\n")
}
func getHello1(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    fmt.Printf("%s: got /hello request\n", ctx.Value(keyServerAddr))
    io.WriteString(w, "Hello, HTTP!\n")
}

func getRoot2(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()

    first := r.URL.Query().Get("first")
    second := r.URL.Query().Get("second")

    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        fmt.Printf("could not read body: %s\n", err)
    }

    fmt.Printf("%s: got / request. first(%t)=%s, second(%t)=%s, body:\n%s\n",
        ctx.Value(keyServerAddr),
        first,
        second,
        body)
    io.WriteString(w, "This is my website 3!\n")
}

func getHello2(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()

    fmt.Printf("%s: got /hello request\n", ctx.Value(keyServerAddr))

    myName := r.PostFormValue("myName")
    if myName == "" {
        w.Header().Set("x-missing-field", "myName")
        w.WriteHeader(http.StatusBadRequest)
        return
    }
    io.WriteString(w, fmt.Sprintf("Hello, %s!\n", myName))
}

func main() {
    http.HandleFunc("/getroot", getRoot)
    http.HandleFunc("/hello/getHello", getHello)
    http.HandleFunc("/hello/sayhello", sayHello)

    http.HandleFunc("/getroot1", getRoot1)
    http.HandleFunc("/gethello1", getHello1)
    http.HandleFunc("/getroot2", getRoot2)
    http.HandleFunc("/gethello2", getHello2)

    err := http.ListenAndServe(":9099", nil)
    log.Println("Starting HTTP server...")
    if errors.Is(err, http.ErrServerClosed) {
    log.Println("server closed")
    } else if err != nil {
    log.Fatal("error starting server:", err)
    os.Exit(1)
    }
}


